<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
    <style>
        html,
        body {
            margin: auto;
            width: 90%;
            padding: 10px;
            font-size: 25px;
            text-align: center;
        }

        button, input {
            height: 40px;
            font-size: 25px;
            margin: 10px;
        }

        form {
            margin: 10px;
        }

        ul, ul {
            list-style: none;
            margin: 0px;
        }

        .努力 {
            color: forestgreen;
        }

        .发呆 {
            color:maroon;
        }

        .休息 {
            color:slateblue;
        }

    </style>
    <title>时间都去哪儿了</title>
</head>

<body>
    <div id="time_tracker"></div>

    <script lang="javascript">

        function dateToText(d) {
            let year = d.getFullYear()
            let month = (d.getMonth() + 1).toString().padStart(2, '0')
            let date = d.getDate().toString().padStart(2, '0')
            let hour = d.getHours().toString().padStart(2, '0')
            let minute = d.getMinutes().toString().padStart(2, '0')
            let second = d.getSeconds().toString().padStart(2, '0')

            return year + "-" + month + "-" + date + " " + hour + ":" + minute + ":" + second
        }

        function formatSeconds(s) {
            result = ""
            if (s >= 3600) {
                result += "" + parseInt(s / 3600) + "小时"
                result = s % 3600
            }
            if (s >= 60) {
                result += "" + parseInt(s / 60) + "分"
                s = s % 60
            }
            result += "" + s + "秒"
            return result
        }

        class ActionItem {
            constructor(action) {
                if (typeof(action) == "string") {
                    this.action = action
                    this.start_time = new Date()
                    this.finish_time = null
                } else if (action != null) {
                    // assign from json object
                    this.action = action.action
                    this.start_time = new Date(action.start_time)
                    this.finish_time = new Date(action.finish_time)
                }
            }

            finish() {
                this.finish_time = new Date()
            }
        }

        class TimeRecord {
            constructor(obj=null) {
                this.items = []
                if (obj) {
                    // assign from json object
                    this.title = obj.title
                    for (let i = 0; i < obj.items.length; i++) {
                        this.items.push(new ActionItem(obj.items[i]))
                    }
                } else {
                    let now = new Date();
                    this.title = dateToText(now)
                }
            }

            last_item() {
                if (this.items.length > 0) {
                    return this.items[this.items.length - 1]
                }
                return null
            }

            start_action(action) {
                let last_item = this.last_item()
                if (last_item == null) {
                    this.items.push(new ActionItem(action))
                } else if (last_item.action == action) {
                    console.log("Ignoring duplicate action", action)
                } else {
                    last_item.finish()
                    this.items.push(new ActionItem(action))
                }
            }

            finish_action() {
                let last_item = this.last_item()
                if (last_item == null) {
                    console.log("No active action")
                } else {
                    last_item.finish()
                }
            }
        }

        class TimeInventory {
            constructor(obj=null) {
                this.items = []
                if (obj != null) {
                    for (let i = 0; i < obj.items.length; i++) {
                        this.items.push(new TimeRecord(obj.items[i]))
                    }
                }
            }

            add_time_record(time_record) {
                this.items.push(time_record)
            }

            clear() {
                this.items = []
            }
        }

        class TimeTracker {
            constructor(div) {
                this.div = div
                this.div_record_list = document.createElement("div")
                this.div_record_new = document.createElement("div")
                this.div_record_display = document.createElement("div")

                this.div.appendChild(this.div_record_list)
                this.div.appendChild(this.div_record_new)
                this.div.appendChild(this.div_record_display)

                // div for record list
                let btn_add_record = document.createElement("button")
                btn_add_record.innerText = "开始记录"
                btn_add_record.onclick = ()=>this.show_add_record()

                let btn_clear = document.createElement("button")
                btn_clear.innerText = "清空"
                btn_clear.onclick = () => this.clear_records()

                this.div_record_list.appendChild(btn_add_record)
                this.div_record_list.appendChild(btn_clear)
                this.ul_record_list = document.createElement("ul")
                this.div_record_list.appendChild(this.ul_record_list)

                // div for creating new record
                this.input_title = document.createElement("input", {type: "text"})
                this.div_record_new.appendChild(this.input_title)

                let btn_working = document.createElement("button")
                btn_working.setAttribute("class", "努力")
                btn_working.innerText = "^_^ 努力 ^_^"
                btn_working.onclick = () => this.on_btn_working()

                let btn_stupid = document.createElement("button", {"class": "发呆"})
                btn_stupid.setAttribute("class", "发呆")
                btn_stupid.innerText = "O_O 发呆 O_O"
                btn_stupid.onclick = () => this.on_btn_stupid()

                let btn_break = document.createElement("button", {"class": "休息"})
                btn_break.setAttribute("class", "休息")
                btn_break.innerText = ">_< 休息 >_<"
                btn_break.onclick = () => this.on_btn_break()

                let div_control = document.createElement("div")
                div_control.appendChild(btn_working)
                div_control.appendChild(btn_stupid)
                div_control.appendChild(btn_break)
                this.div_record_new.appendChild(div_control)

                this.div_status = document.createElement("div")
                this.div_record_new.appendChild(this.div_status)

                let btn_save = document.createElement("button")
                btn_save.innerText = "结束"
                let btn_cancel = document.createElement("button")
                btn_cancel.innerText = "取消"
                let div_buttons = document.createElement("div")
                div_buttons.appendChild(btn_save)
                div_buttons.appendChild(btn_cancel)
                this.div_record_new.appendChild(this.input_title)
                this.div_record_new.appendChild(div_buttons)
                btn_save.onclick = ()=>this.save_record()
                btn_cancel.onclick = ()=>this.giveup_record()

                // div for record detail
                let btn_show_list = document.createElement("button")
                btn_show_list.innerText = "返回"
                btn_show_list.onclick = ()=>this.show_record_list()
                this.div_record_display.appendChild(btn_show_list)
                this.h1_title = document.createElement("h1")
                this.div_record_display.appendChild(this.h1_title)
                this.div_detail_status = document.createElement("div")
                this.div_record_display.appendChild(this.div_detail_status)


                // try to load from local storage
                let saved_inventory = localStorage.getItem("inventory")
                if (saved_inventory != null) {
                    this.inventory = new TimeInventory(JSON.parse(saved_inventory))
                } else {
                    // data
                    this.inventory = new TimeInventory()
                }

                this.stage_record = null

                // view
                this.show_record_list()
            }

            show_record_list() {
                this.div_record_list.style.display = "block"
                this.div_record_new.style.display = "none"
                this.div_record_display.style.display = "none"
                this.stage_record = null

                // show the ul
                this.ul_record_list.innerText = ""
                let tracker = this
                this.inventory.items.map(item => {
                    let x = item
                    let li = document.createElement("li")
                    let a = document.createElement("a")
                    a.setAttribute("href", "#")
                    a.onclick = function() {
                        tracker.show_record_detail(x)
                    }
                    a.innerText = x.title
                    li.appendChild(a)
                    this.ul_record_list.appendChild(li)
                })
            }

            show_add_record() {
                this.div_record_list.style.display = "none"
                this.div_record_new.style.display = "block"
                this.div_record_display.style.display = "none"

                this.stage_record = new TimeRecord()
                this.input_title.value = this.stage_record.title
                this.render_record(this.stage_record, this.div_status)
            }

            show_record_detail(item) {
                this.div_record_list.style.display = "none"
                this.div_record_new.style.display = "none"
                this.div_record_display.style.display = "block"

                this.h1_title.innerText = item.title
                this.render_record(item, this.div_detail_status)
            }

            // render a record to adiv
            render_record(record, div) {
                div.innerText = ""
                if (record.items.length == 0) {
                    div.innerText = "还没开始"
                    return
                }

                let length_map = {
                    "努力": 0,
                    "发呆": 0,
                    "休息": 0
                }
                let summaryText = "一共"
                let actions = Object.keys(length_map)
                actions.map((action) => {
                    let length = 0
                    record.items.map((item) => {
                        if (item.action == action) {
                            length += item.finish_time - item.start_time
                        }
                    })
                    length_map[action] = parseInt(length/1000)
                    summaryText += action + "了" + formatSeconds(length_map[action]) + " "
                })
                let summary = document.createElement("p")
                summary.innerText = summaryText
                div.appendChild(summary)

                // list the action details
                let ul = document.createElement("ul")
                record.items.map((item) => {
                    let li = document.createElement("li")
                    li.setAttribute("class", item.action)
                    li.innerText = item.action + " " + formatSeconds(parseInt((item.finish_time - item.start_time)/1000))
                    ul.appendChild(li)
                })
                div.appendChild(ul)
            }

            start_action(action) {
                let first_action = false
                if (this.stage_record.items.length == 0) {
                    first_action = true
                }
                this.stage_record.start_action(action)
                let tracker = this
                if (first_action) {
                    // start a timer to render the action list
                    let timerHandler = function() {
                        if (tracker.stage_record != null) {
                            tracker.stage_record.finish_action()
                            tracker.render_record(tracker.stage_record, tracker.div_status)
                            setTimeout(timerHandler, 1000)
                        }
                    }
                    setTimeout(timerHandler, 1000)
                }
            }

            on_btn_working() {
                this.start_action("努力")
            }

            on_btn_break() {
                this.start_action("休息")
            }

            on_btn_stupid() {
                this.start_action("发呆")
            }

            save_record() {
                console.log("Saving record " + this.stage_record.title)

                this.inventory.add_time_record(this.stage_record)
                localStorage.setItem("inventory", JSON.stringify(this.inventory))
                this.show_record_list()
            }

            clear_records() {
                console.log("Clearing records")
                this.inventory.clear()
                localStorage.clear()
                this.show_record_list()
            }

            giveup_record() {
                console.log("Giving up record")
                this.show_record_list()
            }
        }

        var timeTracker = new TimeTracker(document.getElementById("time_tracker"))
    </script>
</body>

</html>
